/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package moonnms.libs;

import org.apache.commons.net.telnet.TelnetClient;

import java.io.*;
/**
 *
 * @author Di_Moon
 */
public class libNMSTelnetClient {
    protected TelnetClient telnet = new TelnetClient();
    
    protected InputStream in;
    protected PrintStream out;
    
    protected String cmdPrompt;
    protected String morePattern;
    protected String morePatternCmd;
    
    protected static final char _enter = (char)13;
    
    protected String server;
    protected int port;
    
    // Инициализация класа.
    //    server - фдрес сервера для подключения
    //    port - номер порта
    public libNMSTelnetClient(String Server, int Port) {
        server = Server;
        port = Port;
    }
    
    // Подключение к серверу
    public boolean connect() {
        try {
            // Подключимся к серверу
            telnet.connect(server, port);
            
            // Определим потоки ввода-вывода
            in = telnet.getInputStream();
            out = new PrintStream(telnet.getOutputStream());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    
    // Примерная функция аутентификации
    public boolean login(String username, String password) {
        readUntil("login: ");
        write(username);
        readUntil("Password:");
        write(password);
        readUntil("> ");
        setPrompt("> ");
        
        return true;
    }
   
    // Переход в привиллигированный режим на устройстве
    //  enCmd - команда для перехода в привиллигированный режим
    //  password - пароль для входа в привиллигированный режим
    //  passPrompt - строка предложения ввода пароля
    //  enPrompt - строка-приглашение после входа в привилигированный режим
    public void enable(String enCmd, String password, 
            String passPrompt, String enPrompt) {
        try {
            write(enCmd);
            readUntil(passPrompt);
            write(password);
            readUntil(enPrompt);
            setPrompt(enPrompt);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void setPrompt(String newPrompt) {
        cmdPrompt = newPrompt;
    }
   
    // Установка шаблона для события "more, далее и т.д."
    // pattern - шаблон
    // cmd - 
    public void setMorePattern(String pattern, String cmd) {
        morePattern = pattern;
        morePatternCmd = cmd;
    }
    
    // Отправка команды на Телнет-сервер и возвращение результата её работы
    public String sendCommand(String command) {
        try {
            write(command);
            return readUntil(cmdPrompt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    // Получаем данные с клиента сокета, как только придёт pattern, возвращаем полученные данные
    public String readUntil(String pattern) {
        try {
            boolean haveMorePattern = false;
            int morePatternLength = 0;
            char ch=0;
            
            StringBuffer sb = new StringBuffer();
            int patternLength = pattern.length();
            
            if(morePattern != null) {
                morePatternLength = morePattern.length();
                haveMorePattern = true;
            }
            
            while((ch = (char)in.read()) != 0) {
//                System.out.print(ch);
                sb.append(ch);
                
                // Проверка на выводимость шаблона "more, далее и т.д."
                if(sb.toString().length() >= morePatternLength && morePatternLength > 0) {
                    if(haveMorePattern && sb.toString().endsWith(morePattern)) {
                        out.print(morePatternCmd);
                        out.flush();
                        int lastEnter = sb.lastIndexOf(String.valueOf(_enter));
                        sb.delete(lastEnter, sb.capacity());
                    }
                }
                
                if(sb.toString().length() >= patternLength) {
                    if(sb.toString().endsWith(pattern)) {
                        return sb.toString();
                    }
                }
            };
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
    // Получение данных с клиента, если приходит pattern, то возвращаем данные
    // если приходит specialPattern, возвращаем null
    public String readUntil(String pattern, String specialPattern) {
        try {
            boolean haveMorePattern = false;
            int morePatternLength = 0;
            char ch=0;
            
            StringBuffer sb = new StringBuffer();
            int patternLength = pattern.length();
            int specialPatternLength = specialPattern.length();
            
            if(morePattern != null) {
                morePatternLength = morePattern.length();
                haveMorePattern = true;
            }
            
            while((ch = (char)in.read()) != 0) {
//                System.out.print(ch);
                sb.append(ch);
                
                // Проверка на выводимость шаблона "more, далее и т.д."
                if(sb.toString().length() >= morePatternLength && morePatternLength > 0) {
                    if(haveMorePattern && sb.toString().endsWith(morePattern)) {
                        out.print(morePatternCmd);
                        out.flush();
                        int lastEnter = sb.lastIndexOf(String.valueOf(_enter));
                        sb.delete(lastEnter, sb.capacity());
                    }
                }
                
                if(sb.toString().length() >= specialPatternLength) {
                    if(sb.toString().endsWith(specialPattern)) {
                        return null;
                    }
                }
                
                if(sb.toString().length() >= patternLength) {
                    if(sb.toString().endsWith(pattern)) {
                        return sb.toString();
                    }
                }
            };
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }

    
    // Отправим данные в telnet
    public void write(String data) {
        try {
            out.println(data);
            out.flush();
//            System.out.println("TelnetClient write: "+data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    // Отключимся от сервера
    public void disconnect() {
        try { 
            telnet.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
